from math import log,inf

def Print_Matrix(mat:dict[dict]):
    row_names = tuple(mat.keys())
    print("\t"+"\t".join(mat[row_names[0]].keys()))
    for name in row_names:
        print(name+"\t", end="")
        print("\t".join(map(lambda v:format(v,"0.3f"),mat[name].values())))
    print()

class SquareMatrix(object):
    def __init__(self) -> None:
        self.index2key = []
        self.key2index = {}
        self.mat = []
    
    def add_item(self,key) -> None:
        if key in self.name2index:
            raise ValueError("key already in Matrix")
        self.index2key.append(key)
        self.key2index[key] = len(self.index2key) - 1

    def __getitem__(self,keys) -> float|tuple:
        if isinstance(keys,str):
            if keys in self.names:
                return 
            else:
                raise ValueError("error key")
        elif isinstance(keys,tuple):
            i,j = keys
            if isinstance(i,slice):
                if j in self.colum_name:
                    return tuple([col[j] for col in self.mat.values()])
                else:
                    raise ValueError("error key")
            elif i in self.row_name and j in self.colum_name:
                return self.mat[i][j]
            else:
                raise ValueError("error key")
        else:
            raise ValueError("error key type")
    
    def __setitem__(self,keys:tuple,value) -> None:
        if not isinstance(keys,tuple):
            raise ValueError("error key type")
        
        i,j = keys
        if isinstance(i,slice):
            raise ValueError("error key type")
            
        if i in self.row_name and j in self.colum_name:
            self.mat[i][j] = value
        else:
            raise ValueError("error key")
    
    def keys(self) -> tuple[tuple]:
        return (self.row_name,self.colum_name)
    
    def View(self):
        Print_Matrix(self.mat)


class Node(object):
    def __init__(self,state,step) -> None:
        self.state = state
        self.step = step
        self.value = None
        self.Next = []
    
    def set_value(self,v) -> None:
        self.value = v

    def add_next(self,node:"Node",weight=None) -> None:
        self.Next.append([node,weight])


if __name__ == "__main__":
    pass